//
//  BaseSynchronousData.m
//  synchronous_data
//
//  Created by huimac on 2021/10/27.
//

#import "BaseSynchronousData.h"
#import "SynchronousDataPlugin.h"

@interface SynchronousDataPlugin (ExtMethodInterface)
+(void)syncToFlutterData:(NSString *)uuid data:(NSDictionary *)data complete:(void(^)(void))complete;
+(NSString *)receiveFlutterDataSyncRequest:(void(^)(NSString *uuid, NSDictionary *data))requestBlock;
+(void)removeFlutterDataSyncRequest:(NSString *)flutterDataSyncRequestId;
@end

@interface BaseSynchronousData ()
@property (nonatomic, strong) NSMutableDictionary<NSString *, void(^)(void)> *listnersMap;
@property (nonatomic, copy) NSString *flutterDataSyncRequestId;
@end

@implementation BaseSynchronousData
@synthesize uuid;

-(instancetype)init {
    if(self == [super init]) {
        self.listnersMap = [[NSMutableDictionary alloc] init];
        self.flutterDataSyncRequestId = [self handleReceiveFlutterDataSyncRequest];
    }
    return self;
}



- (nonnull NSDictionary<NSString *,id> *)toJson {
    NSLog(@"warning:此方法需要子类重写...");
    return [@{} mutableCopy];
}
- (nonnull id)toObject:(nonnull NSDictionary<NSString *,id> *)json {
    NSLog(@"warning:此方法需要子类重写...");
    return self;
}

-(NSString *)addListener:(void (^)(void))listner {
    @synchronized (self) {
        if (listner == nil) return nil;
        NSString *listnerId = [[NSUUID UUID] UUIDString];
        [self.listnersMap setValue:listner forKey:listnerId];
        return listnerId;
    }
}

-(BOOL)removeListener:(NSString *)listnerId {
    @synchronized (self) {
        if ([self.listnersMap.keyEnumerator.allObjects containsObject:listnerId]) {
            [self.listnersMap removeObjectForKey:listnerId];
            return YES;
        }
        return NO;
    }
}

-(void)notifyListeners:(void (^)(void))complete {
    @synchronized (self) {
        [self.listnersMap.objectEnumerator.allObjects enumerateObjectsUsingBlock:^(void (^ _Nonnull obj)(void), NSUInteger idx, BOOL * _Nonnull stop) {
            obj();
        }];
        [SynchronousDataPlugin syncToFlutterData:uuid data:[self toJson] complete:complete];
    }
}

-(void)dealloc {
    [SynchronousDataPlugin removeFlutterDataSyncRequest:self.flutterDataSyncRequestId];
}

-(NSString *)handleReceiveFlutterDataSyncRequest {
    __weak typeof(self) weakSelf = self;
    return [SynchronousDataPlugin receiveFlutterDataSyncRequest:^(NSString *uuid, NSDictionary *data) {
        if ([weakSelf.uuid isEqualToString:uuid]) {
            [weakSelf toObject:data];
            @synchronized (weakSelf) {
                for (void (^ obj)(void) in weakSelf.listnersMap.objectEnumerator.allObjects) {
                    obj();
                }
            }
        }
    }];
}

@end

